

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;

public class WebConnection extends Thread {
	// MongoDb Object id of this gameserver
	private String objectId;
	private boolean IsRunning = true;
	
	/** Singleton **/
	private static WebConnection instance = new WebConnection();
	public static WebConnection getInstance()
	{
		return instance;
	}
	
	private WebConnection()
	{
		
	}
	/** Singleton end **/
	
	@Override
	public void run()
	{
		while (this.IsRunning)
		{
			try {
				if (this.objectId == null) // Gameserver is not registered at webserver yet
					registerAtWebservice();
				else // Gameserver is already registered at the webserver
					updateAtWebservice();
				
				// Update the server status (or register) once every 5 seconds
				Thread.sleep(5000);
			} 
			catch (Exception e) 
			{
			}
		}
	}
	
	/**
	 * Notifies the webserver of this gameserver, retrieving this webservers object id.
	 * @return Whether the notification has succeeded or not.
	 */
	private void registerAtWebservice()
	{
		try
		{
			// Construct data
	        String data = URLEncoder.encode("name", "UTF-8") + "=" + URLEncoder.encode("servernaam", "UTF-8");
	        data += "&" + URLEncoder.encode("ip", "UTF-8") + "=" + URLEncoder.encode(Settings.ipAddress, "UTF-8");
	        data += "&" + URLEncoder.encode("port", "UTF-8") + "=" + URLEncoder.encode(String.valueOf(Settings.port), "UTF-8");
	        data += "&" + URLEncoder.encode("maxplayers", "UTF-8") + "=" + URLEncoder.encode(String.valueOf(Settings.maximumAmountOfPlayers), "UTF-8");
	        
	        String currentPlayers = String.valueOf(ConnectionHandler.getInstance().getActiveClients().size());
	        data += "&" + URLEncoder.encode("currentplayers", "UTF-8") + "=" + URLEncoder.encode(currentPlayers, "UTF-8");
	 
	        //Server state (in lobby or playing, etc)
	        data += "&" + URLEncoder.encode("state", "UTF-8") + "=" + URLEncoder.encode(Settings.state, "UTF-8");
	        
	        // Send data
	        URL url = new URL(Settings.registrationUrl);
	        URLConnection conn = url.openConnection();
	        conn.setDoOutput(true);
	        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
	        writer.write(data);
	        writer.flush();
	 
	        // Get the response
	        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	        String line;
	        while ((line = reader.readLine()) != null) {
	            this.objectId = line;
	        }
	        writer.close();
	        reader.close();
		}
		catch (Exception e)
		{	
		}
	}
	
	private void updateAtWebservice()
	{
		try
		{
			// Construct data
	        String data = URLEncoder.encode("objectid", "UTF-8") + "=" + URLEncoder.encode(this.objectId, "UTF-8");
	        String currentPlayers = String.valueOf(ConnectionHandler.getInstance().getActiveClients().size());
	        data += "&" + URLEncoder.encode("currentplayers", "UTF-8") + "=" + URLEncoder.encode(currentPlayers, "UTF-8");
	        data += "&" + URLEncoder.encode("state", "UTF-8") + "=" + URLEncoder.encode(Settings.state, "UTF-8");
	 
	        // Send data
	        URL url = new URL(Settings.registrationUrl);
	        URLConnection conn = url.openConnection();
	        conn.setDoOutput(true);
	        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
	        writer.write(data);
	        writer.flush();
	        
	        // Get the response (required even when response is empty)
	        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	        reader.readLine();
	        
	        writer.close();
	        reader.close();
		}
		catch (Exception e)
		{
		}
	}
	
	/**
	 * Sends scores gained in this server to the webserver.
	 */
	public void uploadScoreData(){
		//Send score data if server is registered.
		if(this.objectId != null){
			try
			{
				//foo[]=val1&foo[]=val2&foo[]=val3
				String data = URLEncoder.encode("objectid", "UTF-8") + "=" + URLEncoder.encode(this.objectId, "UTF-8");
				data += "&" + URLEncoder.encode("scoredata", "UTF-8") + "=";

				ArrayList<Client> players = ConnectionHandler.getInstance().getActiveClients();
				int playerCount = players.size();
				for(int i = 0; i < playerCount; i++){
					Client player = players.get(i);
					if(player.getWebId() != ""){
						String dataItem = player.getWebId() + "#" + player.getPlayerData().getScore();
						if(i > 0) //not the first time
							data += ":";
						data += URLEncoder.encode(dataItem, "UTF-8");
					}
				}

				// Send data
				URL url = new URL(Settings.registrationUrl);
				URLConnection conn = url.openConnection();
				conn.setDoOutput(true);
				OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
				writer.write(data);
				writer.flush();

				// Get the response (required even when response is empty)
				BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				reader.readLine();

				writer.close();
				reader.close();
			}
			catch (Exception e)
			{
			}
		}
	}

}
